/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package compilador.datos;

import java.util.ArrayList;
import javax.swing.JTextArea;

/**
 * Clase que encapsula un buffer donde se almacenan las instrucciones de codigo objeto que
 * se van generando. Permite modificar facilmente las instrucciones de salto cuya instruccion
 * destino no se conoce en el momento de generarse.
 * De cara al resto de clases las instrucciones se numeran de 1 a N
 * @author F. Javier S. Pardo
 */
public class BufferInstruc {
    private ArrayList<String> bufferInstruc = new ArrayList();

    //Control textArea que muestra las instrucciones objeto que se van generando (para facilitar la depuracion)
    private JTextArea textArea = null;

    public void setTextArea (JTextArea textAreaCodigo){
        //Establecer el modo debug
        this.textArea = textAreaCodigo;
    }
    
    /**
     * Añade una instruccion en la ultima posicion del buffer.
     * Proporciona una gestion automatica del numero de instruccion actual.
     * ¡¡OJO!! Etq es el numero DE LA SIGUIENTE INSTRUCCION que se escriba.
     * @param cod : código de la instruccion a emitir
     */
    public void emite(String cod){
        bufferInstruc.add(cod);
        if (this.textArea != null){
            this.textArea.setText(this.textArea.getText() + 
                    this.bufferInstruc.size() +" - "+ cod + "\n");
        }
    }

    /**
     * Devuelve el numero DE LA SIGUIENTE INSTRUCCION que se va a escribir,
     * es un CONTADOR ADELANTADO.
     * @return etq: el número que se asigna a la siguiente instrucción que se escriba
     */
    public int getEtq(){
        return bufferInstruc.size() + 1;
    }

    /**
     * Devuelve el buffer de instrucciones
     * @return Buffer de instrucciones (String)
     */
    public ArrayList<String> getBuffer(){
        return this.bufferInstruc;
    }

    /**
     * Modifica la instruccion de salto especificada, sustituyendo el caracter de interrogacion
     * por la direccion real del salto. Si no se encuentra el caracter '?' devuelve falso, en caso
     * contrario devuelve verdadero.
     * @param dirInstSaltoIgnorante
     * @param dirSaltoConocido
     * @return
     */
    public boolean parchea(int dirInstSaltoIgnorante, int dirSaltoConocido){
        //Primero recupero la instruccion.
        //Externamente las instrucciones van de 1 a N, pero el ArrayList va de 0 a N-1
        String sInstrSalto = this.bufferInstruc.get(dirInstSaltoIgnorante - 1);
        //Localizo la posicion de la interrogacion
        int iposCar = sInstrSalto.indexOf('?');
        //Si NO se encuentra la interrogacion en la instruccion es que algo hemos hecho mal
        if (iposCar == -1)
            return false;
        //Reemplazo la interrogacion por una cadena con el numero de instruccion correspondiente.
        String sNuevaInstr = sInstrSalto.replace("?", String.valueOf(dirSaltoConocido));
        //Reemplazo en el buffer la instruccion original por la modificada
        this.getBuffer().set (dirInstSaltoIgnorante - 1, sNuevaInstr);
        //Pinto todas las instrucciones otra vez
        if (this.textArea != null){
            String sInstr = "";
            for(int i= 0; i < this.bufferInstruc.size(); i++){
                sInstr += (i+1) +" - "+ this.bufferInstruc.get(i) + "\n";
            }
            this.textArea.setText(sInstr);
        }        
        return true;
    }
}
